﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Threading;
using Ideas2Realize.Helpers;
using Ideas2Realize.Data.Models;

namespace Ideas2Realize.Data.Business
{
    /*
     * usersview is view thats is already filtred on deleted is null.
     */

    public class UserRepository : PetaPocoRepository<Models.User>, 
        Interface.IUserRepository
    {

        public Models.User GetById(int id)
        {
            return Single(id);
        }

        public Models.User GetByUsername(string username)
        {
            var query = Query("select * from usersview where username=@0", username);

            if (query.Count() > 0)
                return query.FirstOrDefault();

            return null; 
        }

        /// <summary>
        /// Checks if user exists, if user does not exists it returns NULL.
        /// </summary>
        /// <param name="username">Username such as email or ad-account.</param>
        /// <param name="password">Hashed password</param>
        /// <returns></returns>
        public Models.User AuthenticateUser(string username, string password)
        {
            Models.User user = null;

            string hashed = SecurityHelper.GetHash(password);

            var query = Query("select * from usersview where username=@0 and password=@1", username, hashed);

            if (query.Count() > 0)
                return query.FirstOrDefault(); 

            return user; 
        }

        public void RegisterUser(Models.User user)
        {
            string hashed = SecurityHelper.GetHash(user.Password);
            
            user.Password = hashed;
            user.Created = DateTime.Now;
            user.CreatedBy = Thread.CurrentPrincipal.Identity.Name;
            user.Changed = DateTime.Now;
            user.ChangedBy = Thread.CurrentPrincipal.Identity.Name;

            Insert(user); 
        }

        public IEnumerable<Models.User> GetAll()
        {
            var query = Query("select * from usersview");

            return query;
        }

        public string[] GetRoles(string username)
        {
            var query = db.Fetch<Models.UserRoleView>("select * from userroleview where username=@0", username);

            if (query.Count() == 0)
                return new string[] { };

            List<string> roles = new List<string>(); 
            foreach (var role in query)
            {
                roles.Add(role.Name);
            }

            return roles.ToArray();
        }

        public IEnumerable<Models.PhoneType> GetPhoneTypes()
        {
            return db.Fetch<PhoneType>("select * from phonetypes"); 
        }


        public PetaPoco.Page<User> GetPaged(int limit, int page)
        {
            return PagedQuery(page, limit,"select * from usersview");
        }

        public IEnumerable<Role> GetRoles()
        {
            return db.Fetch<Role>("select * from roles"); 
        }


        public void AddToRole(User user, int roleId)
        {
            UserRole role = new UserRole(); 
         
            role.UserId = user.Id; 
            role.RoleId = roleId;

            Insert(role);
        }


        public UsersView GetViewById(int userId)
        {
            return db.Fetch<UsersView>("select * from usersview where id=@0",userId).SingleOrDefault();
        }

        public UsersView GetViewByUsername(string username)
        {
            return db.Fetch<UsersView>("select * from usersview where username=@0", username).SingleOrDefault();
        }


        public IEnumerable<Department> GetDepartments()
        {
            return db.Fetch<Department>("select * from departments");
        }

        public UsersView GetResponsibleUserByDepartment(int departmentId)
        {
            throw new NotImplementedException();
        }


        public PetaPoco.Page<Department> GetPagedDepartments(int limit, int page)
        {
            return PagedQuery<Department>(page, limit, "select * from departments");
        }

        public void SaveDepartment(Department department)
        {
            if (department.Id > 0)
                db.Update(department, department.Id);
            else
                db.Insert(department); 
        }

        public Department GetDepartmentById(int departmentId)
        {
            return db.Fetch<Department>("select * from departments where id=@0", departmentId).SingleOrDefault();
        }
    }
}
